package com.sdsy.blockchaintrainingback.filter;

import com.sdsy.blockchaintrainingback.context.ThreadLocalContextHolder;
import com.sdsy.blockchaintrainingback.exception.ServiceException;
import com.sdsy.blockchaintrainingback.pojo.user.LoginUser;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import static com.sdsy.blockchaintrainingback.exception.enums.ErrorCodeConstants.AUTH_TOKEN_EXPIRED;
import static com.sdsy.blockchaintrainingback.utils.JwtUtil.parseToken;
import static com.sdsy.blockchaintrainingback.utils.JwtUtil.verifyToken;

/**
 * @Description TODO
 * @Author linzili
 * @Date 2023/9/26 11:35
 * @Version 1.0
 */
@Slf4j
public class AuthFilter implements AsyncHandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(request.getMethod().toUpperCase().equals("OPTIONS")) {
            return true;
        }
        String token = request.getHeader("Authorization");
        if(token == null) {
            throw new ServiceException(AUTH_TOKEN_EXPIRED);
        }
        if(token.startsWith("Bearer")) {
            token = token.replaceFirst("Bearer ", StringUtils.EMPTY);
        }
        if(!verifyToken(token)){
            throw new ServiceException(AUTH_TOKEN_EXPIRED);
        }
        Claims claims = parseToken(token);
        Long userId = Long.valueOf(claims.get("userId").toString());
        String username = (String) claims.get("username");
        LoginUser loginUserDo = new LoginUser(userId, username);
        ThreadLocalContextHolder.setLoginUser(loginUserDo);
        return true;
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
       ThreadLocalContextHolder.remove();
    }
}
